import { _decorator, Component, Animation, SpriteFrame } from 'cc';
import { FSM_PARAMS_TYPE_ENUM } from '../scripts/enums';
import State from './State';
import { SubStateMachine } from './subStateMachine';
const { ccclass, property } = _decorator;

type ParamsValueType = Boolean | Number;

export const getInitParamsTrigget = () => {
    return {
        type: FSM_PARAMS_TYPE_ENUM.TRIGGER,
        value: false,
    };
}

export const getInitParamsNumber = () => {
    return {
        type: FSM_PARAMS_TYPE_ENUM.NUMBER,
        value: 0,
    };
}

export interface IparamsValue {
    type: FSM_PARAMS_TYPE_ENUM,
    value: ParamsValueType,
}

@ccclass('StateMachine')
export abstract class StateMachine extends Component {
    private _currentState: State | SubStateMachine = null;

    _animationComponent: Animation = null;
    _params: Map<string, IparamsValue> = new Map();
    _stateMachines: Map<string, State | SubStateMachine> = new Map();
    _waitingList: Array<Promise<SpriteFrame[]>> = [];

    getParams(paramsName: string) {
        if (this._params.has(paramsName)) return this._params.get(paramsName).value;
    }

    setParams(paramsName: string, value: ParamsValueType) {
        if (this._params.has(paramsName)) {
            this._params.get(paramsName).value = value;
            this.run();
            this.resetTrigger();
        }
    }

    get currentState() { return this._currentState; }

    set currentState(newState: State | SubStateMachine) {
        this._currentState = newState;
        this._currentState.run();
    }

    resetTrigger(): void {
        for (const [type, value] of this._params) {
            if (value.type === FSM_PARAMS_TYPE_ENUM.TRIGGER) value.value = false;
        }
    }

    abstract init(): void;
    abstract run(): void;
}
